#ifndef __DDR__H__
#define __DDR__H__

#include "hme_conf.h"

#ifdef HME_P3

#include "hme_conf.h"
#include "hme_ddrc.h"
#include "hme_ddrphyc.h"

#define DDR_TYPE				3

/** @defgroup _MEM_TYPE
  * @{
  */
enum _MEM_TYPE 
{
	MEM_DDR2,
	MEM_DDR3		
} ;	
/**
  * @}
  */

/** @defgroup DDR_CHIP_INFO
  * @{
  */
typedef struct {
	uint8_t mem_type;                   /*!< ddr type @ref _MEM_TYPE */
	uint8_t Bus_width;	                /*!< bus width of DDR controller, x8, x16 */
	uint8_t Chip_bus_width;	            /*!< bus width of single chip, x8, x16 */
	uint16_t Chip_size;	                /*!< single chip size, unit is MB */
	uint32_t ddr_dfi_clk;
} MEM_CHIP_INFO;								
/**
  * @}
  */


/** @defgroup _BURST_LENGTH
  * @{
  */
enum _BURST_LENGTH
{
	Burst_8=1,
	Burst_16=2		
} ;	
/**
  * @}
  */

/** @defgroup _DQ_WIDTH
  * @{
  */
enum _DQ_WIDTH
{
	DQ8=0,
	DQ16,
	DQ32,
	DQ64	
} ;	
/**
  * @}
  */

/** @defgroup _SDRAM_COL_SIZE
  * @{
  */
enum _SDRAM_COL_SIZE
{
	ROL_BITS_WIDTH_9	=9,
	ROL_BITS_WIDTH_10	=10,	
	ROL_BITS_WIDTH_11	=11
} ;	
/**
  * @}
  */


/** @defgroup _SDRAM_ROW_SIZE
  * @{
  */
enum _SDRAM_ROW_SIZE
{
	ROW_BITS_WIDTH_14	=14,
	ROW_BITS_WIDTH_15	=15,
	ROW_BITS_WIDTH_16	=16
} ;	
/**
  * @}
  */


/** @defgroup _SDRAM_BANK_SIZE
  * @{
  */
enum _SDRAM_BANK_SIZE
{
	_8_BANKS		=0x3,
	_16_BANKS		=0x4
} ;	
/**
  * @}
  */

/** @defgroup SDRAM_RANK_SIZE
  * @{
  */
enum SDRAM_RANK_SIZE
{
	_1_RANK	=0,
	_2_RANK
} ;	
/**
  * @}
  */



/** @defgroup DDR_PHY_MODE
  * @{
  */
enum DDR_PHY_MODE{
	DDR2_PHY = 0, 		
	LPDDR2_PHY,		
	DDR3_PHY,
	LPDDR3_PHY,
	DDR4_PHY,
	LPDDR4_PHY
};								
/**
  * @}
  */


/** @defgroup DDR3MEM
  * @{
  */
typedef struct {
	uint16_t tRP ;  		
	uint16_t tRCD;			
	uint32_t tRAS;

} DDR3MEM;								
/**
  * @}
  */


typedef struct {
	uint8_t 	ddr_type;				//0x00 bit[6,4]
	uint8_t 	wl_dqs_start_point;   	//0x04 bit[15,8]
	uint16_t 	reg_wl_loadmode;		//0x04 bit[31,16]

} INNER_DDR_PHY_INFO;



/**
  * @}
  */

typedef struct {
	uint8_t type;
	uint16_t Chip_size;
	uint8_t burst_length;
	uint8_t dq_width;
	
	struct{
		uint8_t sdram_col_size;
		uint8_t sdram_row_size;
		uint8_t sdram_bank_size;
		uint8_t sdram_rank_size;
	}row_col_info;
  
} INNER_MEM_CHIP_INFO;
/**
  * @}
  */


/**
  * @}
  */

typedef struct
{
	uint16_t trp     		;//offset:0x04
	uint16_t trcd			;
	uint16_t tras_max		;//offset:0x08
	uint16_t tras_min		;//offset:0x0c
	uint16_t trc			;
	uint16_t trrd_s			;//offset:0x10
	uint16_t trrd_l			;
	uint16_t twtr_l			;//offset:0x14
	uint16_t twtr_s			;
	uint16_t twr   			;
	uint16_t tfaw  			;
	uint16_t tccd_l			;//offset:0x18	
	uint16_t tccd_s			;
	uint16_t trtp 			;
	uint16_t trtw 			;
	uint16_t ddrc_tmrr 	   	;//offset:0x1c
	uint16_t ddrc_tmrw 	    ;
	uint16_t ddrc_tmod 	    ;
	uint16_t ddrc_tmrd 	    ;
	uint16_t trefi_x32   	;//offset:0x20
	uint16_t trfc_min    	;
	uint16_t ddrc_txpr 		;//offset:0x24
	uint16_t tcke 			;
	uint16_t tpd 		    ;
	uint16_t ddrc_trp 		;//offset:0x28
	uint16_t ddrc_tdllk 	;
	uint16_t tppd 			;
	uint16_t tccd_mw 	    ;
	uint16_t ddrc_txp 		;//offset:0x2c
	uint16_t ddrc_trpa 	    ;
	uint16_t ddrc_tescke 	;
	uint16_t tckesr 	    ;
	uint16_t ddrc_trd2mrr 	;//offset:0x38
	uint16_t ddrc_tmrr2mrw  ;
	uint16_t ddrc_tmrr2wr 	;
	uint16_t ddrc_tmrr2rd   ;
	uint16_t tzqoper  		;//offset:0x30
	uint16_t txs     		; 
	uint16_t derated_trp      ;//offset:0x40
	uint16_t derated_trcd     ;
	uint16_t derated_tras_min ;//offset:0x44
	uint16_t derated_trc      ;
	uint16_t derated_trrd_s   ;//offset:0x48
	uint16_t derated_trrd_l   ;
	uint16_t tzqinit        ;//offset:0x4c
	uint16_t treset_h_x1024	;
	uint16_t treset_l_x1024	;
	
}INNER_DDRC_TIMING_INFO;
/**
  * @}
  */


/** @defgroup INNER_DDRC_TIMING_INFO
  * @{
  */
extern const INNER_DDRC_TIMING_INFO DDRC_TIMING_INFO[];		/*!< Pre-defined DDR3 Timing in library */
#define DDR3_400		  	0
#define DDR3_667        	1
#define DDR3_533        	2
/**
  * @}
  */

/** @defgroup INNER_MEM_CHIP_INFO
  * @{
  */
extern const INNER_MEM_CHIP_INFO DDR_INFO[];
/**
  * @}
  */


/** @defgroup INNER_DDR_PHY_INFO
  * @{
  */
extern const INNER_DDR_PHY_INFO DDR_PHY_INFO[];
/**
  * @}
  */
  

//bool DDRC_PHYC_Init(const MEM_CHIP_INFO *chip_info, const void *ddr);
bool DDRC_PHYC_Init(const MEM_CHIP_INFO *chip_info,const void *timing_info,const void *phy_info);
void DDRC_Timing_Config(const void *timing_info);
void DDR_INIT(void);

#define DDR_CTRL_BASE                 				0x51008000UL
#define DDR_PHY_CTRL_BASE                 			0x51002000UL

#define DDRC                    			  		((DDR_CTRL_Type*) DDR_CTRL_BASE)
#define DDR_PHYC                    				((DDRPHY_CTRL_Type*) DDR_PHY_CTRL_BASE)

#endif

#endif
